import { LinkedList, Node } from "./linked_list.js";

class DoublyNode extends Node {
    constructor(element) {
        super(element);//super可以初始化父类里面的数据  this.element,this.next
        this.prev = null;
    }
}

export class DoublyLinkedList extends LinkedList{  
    constructor() {
        super();//构造函数super初始化里面的数据
        this.tail = null;//微博节点
    }
    //append(element):向末尾添加一个新的项
    append(element) {
        //1.根据element创建我们元素
        const newNode = new DoublyNode(element);
        //2.追加元素
        if(this.head === null) { //和this.length === 0 都可以进行判断
            this.head = newNode;//头部结点
            this.tail = newNode;//尾部结点
        } else {
            //查询最后一个结点
            this.tail.next = newNode;//把当前tail的下一个指向给要添加的结点
            newNode.prev = this.tail;//把要添加的newNode结点的前一个指向当前tail
            this.tail = newNode;//最后将  要在改变tail的指向之前，要先把当前tail的内容的指向进行调整，不然链表会出问题
        }
        this.length++;
    }

    //insert(position, element)：向列表的特定位置插入一个新的项
    insert(position, element) {
        const newNode = new DoublyNode(element);//创建一个新的结点
        //1.判断越界问题
        if(position < 0 || position > this.length) return false;
        //插入元素
        if(position === 0) {    //当要插入的位置为首部时
            if(this.head === null) {//当插入位置为首且当前链表没有任何结点时
                this.head = newNode;
                this.tail = newNode;
            } else {    //当前链表有结点时
                newNode.next = this.head;
                this.head.prev = newNode;
                this.head = newNode;
            }
        } else if(position === this.length) {   //当要插入的位置为尾部时
            this.tail.next = newNode;
            newNode.prev = this.tail;
            this.tail = newNode;
        } else {//要插入的位置为链表中间部位时
            let index = 0;
            let current = this.head;
            let previous = null;
            while(index++ < position) {
                previous = current;//要插入位置的前一个结点位置
                current = current.next;//要插入的结点位置
            }
            //进行交换节点
            previous.next = newNode;
            newNode.prev = previous;
            newNode.next = current;
            current.prev = newNode;
        }
        this.length++;
    }
    //get(position)：获取对应位置的元素
    get(position) {
        if(position < 0 || position > this.length - 1) return false; //判断越界 
        let index = 0;
        let current = this.head;
        while(index++ < position) {
            current = current.next;
        }
        return current.element;
    }
    //indexOf(element):返回元素在列表中的索引。如果列表中没有该元素返回-1
    indexOf(element) {
        let index = 0;
        let current = this.head;
        while(current) {
            if(current.element === element) {
                return index;
            }
            index++;
            current = current.next
        }
        return -1;
    }
    //update(position, element): 修改某个位置的元素
    update(position, element) {
        //判断越界问题
		if (position < 0 || position > this.length - 1) return false;
		//1.先删除位置上的元素
		const result = this.removeAt(position);
		//2。插入该位置上的元素
		this.insert(position, element);
		//返回更新的值
		return result;
    }
    //removeAt(position):从列表的特定的位置移除一项
    removeAt(position) {
        //越界
        if(position < 0 || position > this.length - 1) return null;
        //删除
        let current = this.head;//变量提升 为了return  current.element
        if(position === 0){
            if(this.length === 1) {
                this.head = null;
                this.tail = null;
            } else {
                this.head = this.head.next;
                this.head.prev = null;
            }
        } else if(position === this.length - 1){
            current = this.tail;//变量提升balabal
            this.tail.prev.next = null;
            this.tail = this.tail.prev;
        } else {
            let index = 0;
            let previous = null;
            while(index++ < position) {
                previous = current;
                current = current.next;
            }
            previous.next = current.next;
            current.next.prev = previous;
        }
        this.length--;
        return current.element;
    }
    //remove(element):从列表中移除一项
    remove(element) {
        const position = this.indexOf(element);//获取要移除的项的位置信息
        if(position === -1) {
            return -1;
        } else {
            this.removeAt(position);
        }
    }
    //isEmpty()：如果链表中不包含任何元素，返回true，如果链表长度大于0则返回false
    isEmpty() {
        return this.length === 0;
    }
    //size():返回链表包含的元素个数，与数组的length属性类似
    size() {
        return this.length;
    }
}
